home *** CD-ROM | disk | FTP | other *** search
/ TeX 1995 July / TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO / dviware / dvibook / libtex / tfmfont.c < prev    next >
C/C++ Source or Header  |  1994-03-18  |  6KB  |  261 lines

  1. /*
  2.  * Copyright (c) 1987, 1989 University of Maryland
  3.  * Department of Computer Science.  All rights reserved.
  4.  * Permission to copy for any purpose is hereby granted
  5.  * so long as this copyright notice remains intact.
  6.  */
  7.  
  8. #ifndef lint
  9. static char rcsid[] = "$Header: /usr/src/local/tex/local/mctex/lib/RCS/tfmfont.c,v 3.4 89/11/29 02:29:58 chris Exp $";
  10. #endif
  11.  
  12. #include <stdio.h>
  13. #include <sys/types.h>
  14. #include <sys/stat.h>
  15. #include "types.h"
  16. #include "conv.h"
  17. #include "font.h"
  18. #include "tfm.h"
  19.  
  20. /*
  21.  * TFM font operations.  This defines three fonts:
  22.  *
  23.  *    box   - prints as little square boxes, outlining what TeX
  24.  *        thinks is the character; carries a warning.
  25.  *    blank - prints as entirely blank; carries a warning.
  26.  *    tfm   - prints as entirely blank; can be used for built-in fonts.
  27.  *    invis - an alias for tfm.
  28.  *
  29.  * The first two also complain that no font is available in the
  30.  * requested size; these are intended to be used as a last resort
  31.  * so that users can always print DVI files.  You should configure
  32.  * in exactly one of box or blank.
  33.  *
  34.  * TODO:
  35.  *    base box edge widths on Conversion.c_dpi
  36.  */
  37. static int box_read(), blank_read(), tfm_read();
  38. static int tfm_getgly(), tfm_rasterise();
  39. static void tfm_freefont();
  40.  
  41.     /* magnifications are unused in tfm fonts */
  42. struct    fontops boxops =    /* `boxtops'?  Is this a cereal driver? */
  43.  { "box", 1, 0.0, box_read, tfm_getgly, tfm_rasterise, tfm_freefont };
  44. struct    fontops blankops =
  45.  { "blank", 2, 0.0, blank_read, tfm_getgly, tfm_rasterise, tfm_freefont };
  46. struct    fontops tfmops =
  47.  { "tfm", 0, 0.0, tfm_read, tfm_getgly, tfm_rasterise, tfm_freefont };
  48. struct    fontops invisops =
  49.  { "invis", 0, 0.0, tfm_read, tfm_getgly, tfm_rasterise, tfm_freefont };
  50.  
  51. /*
  52.  * Local info.
  53.  */
  54. struct tfm_details {
  55.     int    tfm_edge;        /* box edge widths, in pixels */
  56.     struct    tfmdata tfm_data;    /* the TFM file data */
  57. };
  58.  
  59. /*
  60.  * Get the tfm_details from font f.
  61.  */
  62. #define    ftotfm(f) ((struct tfm_details *)(f)->f_details)
  63.  
  64. static int do_read();
  65.  
  66. extern    int errno;
  67. char    *malloc();
  68.  
  69. /*
  70.  * Read a Box font.
  71.  */
  72. static int
  73. box_read(f, fd)
  74.     struct font *f;
  75.     int fd;
  76. {
  77.  
  78.     return (do_read(f, fd, 0));
  79. }
  80.  
  81. /*
  82.  * Read a Blank font.
  83.  */
  84. static int
  85. blank_read(f, fd)
  86.     struct font *f;
  87.     int fd;
  88. {
  89.  
  90.     return (do_read(f, fd, 1));
  91. }
  92.  
  93. /*
  94.  * Read a TFM font.
  95.  */
  96. static int
  97. tfm_read(f, fd)
  98.     struct font *f;
  99.     int fd;
  100. {
  101.  
  102.     return (do_read(f, fd, 1));
  103. }
  104.  
  105. /*
  106.  * Read a TFM font.  It is blank if `blank'.
  107.  */
  108. static int
  109. do_read(f, fd, blank)
  110.     register struct font *f;
  111.     int fd, blank;
  112. {
  113.     register struct tfm_details *tfm;
  114.     FILE *fp;
  115.  
  116.     if ((fp = fdopen(fd, "r")) == NULL) {
  117.         (void) close(fd);
  118.         return (-1);
  119.     }
  120.     if ((tfm = (struct tfm_details *)malloc(sizeof *tfm)) == NULL)
  121.         goto fail;
  122.     if (readtfmfile(fp, &tfm->tfm_data, blank))
  123.         goto fail;
  124.     if (blank)
  125.         tfm->tfm_edge = 0;
  126.     else
  127.         tfm->tfm_edge = 2;    /* XXX should be based on dpi */
  128.     if (FontHasGlyphs(f, tfm->tfm_data.t_hdr.th_bc,
  129.               tfm->tfm_data.t_hdr.th_ec + 1))
  130.         goto fail;
  131.     f->f_checksum = 0;        /* ??? */
  132.     f->f_design_size = 0;        /* ??? */
  133.     f->f_hppp = 0;
  134.     f->f_vppp = 0;
  135.     f->f_details = (char *)tfm;
  136.     (void) fclose(fp);
  137.     return (0);
  138.  
  139. fail:
  140.     (void) fclose(fp);
  141.     if (tfm != NULL)
  142.         free((char *)tfm);
  143.     return (-1);
  144. }
  145.  
  146. /*
  147.  * Obtain the specified range of glyphs.
  148.  */
  149. static int
  150. tfm_getgly(f, l, h)
  151.     register struct font *f;
  152.     int l;
  153.     register int h;
  154. {
  155.     register struct tfm_details *tfm = ftotfm(f);
  156.     register struct glyph *g;
  157.     register int i;
  158.     register struct char_info_word *ci;
  159. #define    t (&tfm->tfm_data)
  160.     i32 ScaleOneWidth();
  161. #define ftop(fix) fromSP(ScaleOneWidth(fix, f->f_dvimag))
  162.  
  163.     for (i = l; i < h; i++) {
  164.         ci = &t->t_ci[i - t->t_hdr.th_bc];
  165.         /* zero widths mark invalid characters */
  166.         if (ci->ci_width == 0)
  167.             continue;
  168.         g = f->f_gly[i];
  169.         g->g_flags = GF_VALID;
  170.         g->g_rawtfmwidth = t->t_width[UnSign8(ci->ci_width)];
  171.         g->g_xorigin = 0;
  172.         if (tfm->tfm_edge != 0) {
  173.             g->g_yorigin = ftop(t->t_height[T_CI_H(ci)]);
  174.             g->g_width = ftop(g->g_rawtfmwidth);
  175.             g->g_height = g->g_yorigin +
  176.                 ftop(t->t_depth[T_CI_D(ci)]);
  177.         } else {
  178.             g->g_yorigin = 0;
  179.             g->g_width = 0;
  180.             g->g_height = 0;
  181.         }
  182.     }
  183.     return (0);
  184. #undef t
  185. }
  186.  
  187. /*
  188.  * Obtain rasters for the specified glyphs.
  189.  *
  190.  * IGNORES tfm->tfm_edge: 2 HARDCODED FOR NOW
  191.  */
  192. static int
  193. tfm_rasterise(f, l, h)
  194.     struct font *f;
  195.     int l, h;
  196. {
  197.     register struct glyph *g;
  198.     register char *p;
  199.     register int w, j, i;
  200.     struct tfm_details *tfm = ftotfm(f);
  201. #define EDGE 2
  202.  
  203.     if (tfm->tfm_edge == 0)
  204.         return (0);
  205. if (tfm->tfm_edge != 2) panic("tfm_rasterise");
  206.     for (i = l; i < h; i++) {
  207.         g = f->f_gly[i];
  208.         if ((g->g_flags & GF_VALID) == 0 || !HASRASTER(g))
  209.             continue;
  210.         w = (g->g_width + 7) >> 3;
  211.         p = malloc((unsigned) (g->g_height * w));
  212.         if (p == NULL)
  213.             return (-1);
  214.         g->g_raster = p;
  215.         g->g_rotation = ROT_NORM;
  216.         if (g->g_width < 2 * EDGE) {
  217.             w = 2 * EDGE - g->g_width;
  218.             for (j = g->g_height; --j >= 0;)
  219.                 *p++ = 0xf0 << w;
  220.         } else {
  221.             bzero(p, g->g_height * w);
  222.             for (j = 0; j < g->g_height;) {
  223.                 if (j < EDGE || j >= g->g_height - EDGE) {
  224.                     register int k = w;
  225.  
  226.                     while (--k > 0)
  227.                         *p++ = 0xff;
  228.                     *p++ = 0xff << ((8 - g->g_width) & 7);
  229.                     j++;
  230.                     continue;
  231.                 }
  232.                 /* the following depends on EDGE==2 */
  233.                 *p = 0xc0;
  234.                 p += w - ((g->g_width & 7) == 1 ? 2 : 1);
  235.                 *p++ |= 0xc0 >> ((g->g_width - EDGE) & 7);
  236.                 if ((g->g_width & 7) == 1)
  237.                     *p++ = 0x80;
  238.                 /* end dependencies */
  239.                 if (++j == EDGE && g->g_height >= 2 * EDGE) {
  240.                     register int n = g->g_height - EDGE;
  241.  
  242.                     p += (n - j) * w;
  243.                     j = n;
  244.                 }
  245.             }
  246.         }
  247.     }
  248.     return (0);
  249. }
  250.  
  251. /*
  252.  * Discard the font details.
  253.  */
  254. static void
  255. tfm_freefont(f)
  256.     struct font *f;
  257. {
  258.  
  259.     free(f->f_details);
  260. }
  261.